package com.jinzhi.jzweb.service.impl;

import cn.afterturn.easypoi.word.WordExportUtil;
import cn.afterturn.easypoi.word.entity.WordImageEntity;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.jinzhi.common.constants.MessagesEnum;
import com.jinzhi.common.utils.Result;
import com.jinzhi.common.utils.ShiroUtils;
import com.jinzhi.common.utils.StringUtil;
import com.jinzhi.jzapi.domain.UserDO;
import com.jinzhi.jzweb.domain.*;
import com.jinzhi.jzweb.domain.param.ContractQuery;
import com.jinzhi.jzweb.domain.vo.JazUserOrderVO;
import com.jinzhi.jzweb.service.*;
import com.jinzhi.sys.service.UserService;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.jinzhi.jzweb.dao.JazSysContractDao;
import com.jinzhi.common.base.CoreServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <pre>
 *
 * </pre>
 * <small> 2023-04-18 09:11:44 | Long</small>
 */
@Service
public class JazSysContractServiceImpl extends CoreServiceImpl<JazSysContractDao, JazSysContractDO> implements JazSysContractService {

    //获取项目的根路径
    @Value("${easypoi.path}")
    private String classPath;

    private UserService userService;

    private JazInterviewService jazInterviewService;

    private final JazSysProjectService jazSysProjectService;

    private final JazUserOrderService jazUserOrderService;

    private final JazSysContractTemplateService jazSysContractTemplateService;

    private final JazMessageService jazMessageService;

    public JazSysContractServiceImpl(UserService userService, JazInterviewService jazInterviewService, JazSysProjectService jazSysProjectService, JazUserOrderService jazUserOrderService, JazSysContractTemplateService jazSysContractTemplateService, JazMessageService jazMessageService) {
        this.userService = userService;
        this.jazInterviewService = jazInterviewService;
        this.jazSysProjectService = jazSysProjectService;
        this.jazUserOrderService = jazUserOrderService;
        this.jazSysContractTemplateService = jazSysContractTemplateService;
        this.jazMessageService = jazMessageService;
    }

    /**
     * 分页查询合同信息
     *
     * @return
     */
    @Override
    public Page<?> getSysContractPage(ContractQuery contractQuery) {
        Wrapper wrapper = new EntityWrapper<JazUserOrderDO>()
                .eq(StringUtil.notEmpty(contractQuery.getProjectId()), "project_id", contractQuery.getProjectId())
//                .eq(Objects.nonNull(contractQuery.getStatus()), "status", contractQuery.getStatus())
                .like(StringUtil.notEmpty(contractQuery.getInitiatorName()),"name_jia",contractQuery.getInitiatorName())
                .like(StringUtil.notEmpty(contractQuery.getSignedName()),"name_yi",contractQuery.getSignedName())
                .eq("order_type",2);
        if (contractQuery.getStatus() != null) {
            wrapper.eq("conclude_status",contractQuery.getStatus());
        }else {
            wrapper.eq("conclude_status",2).or().eq("conclude_status",4);
        }
        Page<JazUserOrderDO> jazUserOrderDOPage = jazUserOrderService.selectPage(new Page<>(contractQuery.getPageNumber(), contractQuery.getPageSize()), wrapper);
        //封装版本号
        jazUserOrderDOPage.getRecords().forEach(a->{
            if (a.getContractId()!=null){
                JazSysContractTemplateDO jazSysContractTemplateDO = jazSysContractTemplateService.selectById(a.getContractId());
                if (jazSysContractTemplateDO!=null){
                    a.setVersion(jazSysContractTemplateDO.getVersion());
                }
            }else {
                a.setVersion("1.0");
            }
        });

        //查询项目类型
        List<String> projectIds = jazUserOrderDOPage.getRecords().stream().filter(a -> Objects.nonNull(a.getProjectId())).
                map(JazUserOrderDO::getProjectId).distinct().collect(Collectors.toList());
        if (ObjectUtils.isEmpty(projectIds)) {
            return jazUserOrderDOPage;
        }
        List<String> projectIds1 = new ArrayList<>();
        for (int i = 0; i < projectIds.size(); i++) {
            projectIds1.addAll(Arrays.asList(projectIds.get(i).split(",")));
        }
        List<JazSysProjectDO> jazSysProjectDOS = jazSysProjectService.selectList(new EntityWrapper<JazSysProjectDO>().in("id", projectIds1));
        jazUserOrderDOPage.getRecords().forEach(a -> {
            a.setProjectName(jazSysProjectDOS.stream().filter(b -> Objects.nonNull(a.getProjectId())).
                    filter(b -> a.getProjectId().contains(b.getId().toString())).map(JazSysProjectDO::getName).collect(Collectors.joining(",")));
        });
        return jazUserOrderDOPage;
    }

    /**
     * 根据id查询合同详情
     * @param id
     * @return
     */
    @Override
    public JazUserOrderDO getSysContractById(Long id) {
        JazUserOrderDO jazUserOrderDO = jazUserOrderService.selectById(id);
        if (jazUserOrderDO==null) {
            return jazUserOrderDO;
        }
        // 线上签署的合同
        if (jazUserOrderDO.getContractId()!=null && jazUserOrderDO.getContractType()==0){
            JazSysContractTemplateDO jazSysContractTemplateDO = jazSysContractTemplateService.selectById(jazUserOrderDO.getContractId());
            if (jazSysContractTemplateDO!=null){
                jazUserOrderDO.setVersion(jazSysContractTemplateDO.getVersion());
            }
            // 拼接合同 todo
            //this.userOrderExport(Long.toString(id),response);
        }else if (jazUserOrderDO.getContractType()==1){
            jazUserOrderDO.setVersion("1.0");
        }

        // 查询项目名称
        if (StringUtil.notEmpty(jazUserOrderDO.getProjectId())) {
            String[] projects = jazUserOrderDO.getProjectId().split(",");
            List<JazSysProjectDO> jazSysProjectDOS = jazSysProjectService.selectList(new EntityWrapper<JazSysProjectDO>().in("id", projects));
            jazUserOrderDO.setProjectName(jazSysProjectDOS.stream().map(JazSysProjectDO::getName).collect(Collectors.joining(",")));
        }
        return jazUserOrderDO;
    }

    /**
     * 新增合同
     *
     * @param jazUserOrderDO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertSysContract(JazUserOrderDO jazUserOrderDO) {
        // 查询合同模板id
        JazSysContractTemplateDO jazSysContractTemplateDO = jazSysContractTemplateService.selectOne(new EntityWrapper<JazSysContractTemplateDO>()
                .eq("project_id", jazUserOrderDO.getProjectId()));
        if (jazSysContractTemplateDO!=null){
            jazUserOrderDO.setContractId(jazSysContractTemplateDO.getId());
        }
        jazUserOrderDO.setNumber(tweenRandom());
        jazUserOrderDO.setOrderSource(0);
        jazUserOrderDO.setStatus(0); // 订单待开始状态
        jazUserOrderDO.setConcludeStatus(2); // 合同已签署
        jazUserOrderDO.setContractType(1);
        jazUserOrderDO.setOrderType(2);
        Boolean aBoolean = jazUserOrderService.insert(jazUserOrderDO);

        /** 发送消息 */
        //发给用户
        JazMessageDO jazMessageDO = new JazMessageDO();
        jazMessageDO.setMessageType(1);
        jazMessageDO.setSenderId(jazUserOrderDO.getSigningId());
        jazMessageDO.setReceiverId(jazUserOrderDO.getInitiateId());
        jazMessageDO.setMessageContent(MessagesEnum.MESSAGE_110.getMsg());
        jazMessageDO.setMessageNum(MessagesEnum.MESSAGE_110.getNum());
        jazMessageDO.setHasSendSms(true);
        jazMessageDO.setUserOrderId(jazUserOrderDO.getId());
        jazMessageService.senMessage(jazMessageDO);
        //发给阿姨
        JazMessageDO jazMessageDO2 = new JazMessageDO();
        jazMessageDO2.setMessageType(1);
        jazMessageDO2.setSenderId(jazUserOrderDO.getInitiateId());
        jazMessageDO2.setReceiverId(jazUserOrderDO.getSigningId());
        jazMessageDO2.setMessageContent(MessagesEnum.MESSAGE_111.getMsg());
        jazMessageDO2.setMessageNum(MessagesEnum.MESSAGE_111.getNum());
        jazMessageDO2.setHasSendSms(true);
        jazMessageDO2.setUserOrderId(jazUserOrderDO.getId());
        jazMessageService.senMessage(jazMessageDO2);
        return aBoolean;
    }

    /**
     * 新增合同--发起方
     *
     * @return
     */
    @Override
    public List<JazUserOrderVO> initiator() {
        List<JazUserOrderVO> jazUserContractVOArrayList = new ArrayList<>();
        // 获取面试通过的列表
        List<JazInterviewDO> jazInterviewDOList = jazInterviewService.selectList(
                new EntityWrapper<JazInterviewDO>().eq("result", 1));
        if (jazInterviewDOList == null) {
            return jazUserContractVOArrayList;
        }
        // 去重数据
        List<JazInterviewDO> uniqueInterviewerList = jazInterviewDOList.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toMap(JazInterviewDO::getInviterId, Function.identity(), (oldValue, newValue) -> oldValue),
                        map -> new ArrayList<>(map.values()))
                );
        // 组装数据
        uniqueInterviewerList.forEach(jazInterviewDO -> {
            JazUserOrderVO jazUserOrderVO = new JazUserOrderVO();
                // 线下进行的面试
                jazUserOrderVO.setProjectId(jazInterviewDO.getProjectId());
                jazUserOrderVO.setInitiateId(jazInterviewDO.getInviterId());
                jazUserOrderVO.setSigningId(jazInterviewDO.getInviteeId());
                // 查询发起方信息
                UserDO userDO = userService.selectById(jazUserOrderVO.getInitiateId());
                if (userDO == null) {
                    return;
                }
                if (StringUtil.notEmpty(userDO.getName())){
                    jazUserOrderVO.setNameJia(userDO.getName());
                }else {
                    jazUserOrderVO.setNameJia(userDO.getNickname());
                }
                if (StringUtil.notEmpty(userDO.getMobile())){
                    jazUserOrderVO.setPhoneJia(userDO.getMobile());
                }
                StringBuffer buffer = new StringBuffer();
                // 拼接详细地址
                if (StringUtil.notEmpty(userDO.getProvince())){
                    buffer.append(userDO.getProvince());
                }
                if (StringUtil.notEmpty(userDO.getCity())){
                    buffer.append(userDO.getCity());
                }
                if (StringUtil.notEmpty(userDO.getDistrict())){
                    buffer.append(userDO.getDistrict());
                }
                if (StringUtil.notEmpty(userDO.getDetailedAddress())){
                    buffer.append(userDO.getDetailedAddress());
                }
                jazUserOrderVO.setHomeAddressJia(buffer.toString());
                //jazUserOrderVO.setIdNumber(userDO.getIdNumber());

                // 查询项目名称
                if (StringUtil.notEmpty(jazUserOrderVO.getProjectId())) {
                    String[] projects = jazUserOrderVO.getProjectId().split(",");
                    List<JazSysProjectDO> jazSysProjectDOS = jazSysProjectService.selectList(new EntityWrapper<JazSysProjectDO>().in("id", projects));
                    jazUserOrderVO.setProjectName(jazSysProjectDOS.stream().map(JazSysProjectDO::getName).collect(Collectors.joining(",")));
                }
            jazUserContractVOArrayList.add(jazUserOrderVO);
        });
        return jazUserContractVOArrayList;
    }

    /**
     * 新增合同--签约方
     *
     * @return
     */
    @Override
    public List<JazUserOrderVO> signed() {
        List<JazUserOrderVO> jazUserContractVOArrayList = new ArrayList<>();
        // 获取面试通过的列表
        List<JazInterviewDO> jazInterviewDOList = jazInterviewService.selectList(new EntityWrapper<JazInterviewDO>()
                .eq("result", 1));
        if (jazInterviewDOList == null) {
            return jazUserContractVOArrayList;
        }
        // 组装数据
        jazInterviewDOList.stream().forEach(jazInterviewDO -> {
            JazUserOrderVO jazUserOrderVO = new JazUserOrderVO();
            // 线下进行的面试
            jazUserOrderVO.setProjectId(jazInterviewDO.getProjectId());
            jazUserOrderVO.setInitiateId(jazInterviewDO.getInviterId());
            jazUserOrderVO.setSigningId(jazInterviewDO.getInviteeId());
            // 查询签约方信息
            UserDO userSignedDO = userService.selectById(jazUserOrderVO.getSigningId());
            if (userSignedDO == null) {
                return;
            }
            if (StringUtil.notEmpty(userSignedDO.getName())){
                jazUserOrderVO.setNameYi(userSignedDO.getName());
            }
            if (StringUtil.notEmpty(userSignedDO.getOrderPhone())){
                jazUserOrderVO.setPhoneYi(userSignedDO.getOrderPhone());
            }

            StringBuffer buffer1 = new StringBuffer();
            // 拼接详细地址
            if (StringUtil.notEmpty(userSignedDO.getProvince())){
                buffer1.append(userSignedDO.getProvince());
            }
            if (StringUtil.notEmpty(userSignedDO.getCity())){
                buffer1.append(userSignedDO.getCity());
            }
            if (StringUtil.notEmpty(userSignedDO.getDistrict())){
                buffer1.append(userSignedDO.getDistrict());
            }
            if (StringUtil.notEmpty(userSignedDO.getDetailedAddress())){
                buffer1.append(userSignedDO.getDetailedAddress());
            }
            jazUserOrderVO.setHomeAddressYi(buffer1.toString());
            jazUserOrderVO.setIdentityCardYi(userSignedDO.getIdNumber());

            // 查询项目名称
            if (StringUtil.notEmpty(jazUserOrderVO.getProjectId())) {
                String[] projects = jazUserOrderVO.getProjectId().split(",");
                List<JazSysProjectDO> jazSysProjectDOS = jazSysProjectService.selectList(new EntityWrapper<JazSysProjectDO>().in("id", projects));
                jazUserOrderVO.setProjectName(jazSysProjectDOS.stream().map(JazSysProjectDO::getName).collect(Collectors.joining(",")));
            }

            jazUserContractVOArrayList.add(jazUserOrderVO);
        });
        return jazUserContractVOArrayList;
    }

    /**
     * 修改启用状态
     *
     * @param contractQuery
     * @return
     */
    @Override
    public Result updateContractStatus(ContractQuery contractQuery) {
        JazUserOrderDO jazUserOrderDO = jazUserOrderService.selectById(contractQuery.getUserOrderId());
        if (jazUserOrderDO==null) {
            return Result.fail();
        }
        jazUserOrderDO.setConcludeStatus(contractQuery.getStatus());
        boolean update = jazUserOrderService.updateById(jazUserOrderDO);
        return update?Result.ok():Result.fail();
    }

    /**
     * 拼接带签名的合同信息
     * @param orderId
     * @param response
     */
    public void userOrderExport (String orderId, HttpServletResponse response){
        JazUserOrderDO jazUserOrderDO = jazUserOrderService.selectById(orderId);
        JazSysContractTemplateDO jazSysContractDO = jazSysContractTemplateService.selectById(jazUserOrderDO.getContractId());
        String filename ="";
        String wjm = "";
        if (jazSysContractDO.getName().contains("月嫂")){
            wjm = "ysht";
        }
        if (jazSysContractDO.getName().contains("产后恢复")){
            wjm = "chhfht";
        }
        if (jazSysContractDO.getName().contains("保姆")){
            wjm = "bmht";
        }
        if (jazSysContractDO.getName().contains("老人陪护")){
            wjm = "lrphht";
        }
        if (jazSysContractDO.getName().contains("医护照料")){
            wjm = "yhzlht";
        }
        if (jazSysContractDO.getName().contains("育婴早教")){
            wjm = "yyzjht";
        }
        if (jazSysContractDO.getName().contains("钟点工")){
            wjm = "zdght";
        }
        if (jazSysContractDO.getName().contains("育儿嫂")){
            wjm = "yrsht";
        }

        try {
            documentWord(jazUserOrderDO,response,filename,wjm);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void documentWord(JazUserOrderDO jazUserOrderDO,HttpServletResponse response,String filename,String wjm) throws Exception{
        //导出组装数据
        Map<String,Object> params =new HashMap<>();
        params.put("jfxm",jazUserOrderDO.getNameJia()); //甲方姓名
        params.put("jfsfzhm",jazUserOrderDO.getIdentityCardJia()); //甲方身份证号码
        params.put("jfzz", jazUserOrderDO.getAddress()); //甲方地址
        params.put("jflxdh",jazUserOrderDO.getPhoneJia()); //甲方电话

        //甲方手写签名
        WordImageEntity jfImageEntity =new WordImageEntity();
        jfImageEntity.setHeight(40);
        jfImageEntity.setWidth(34);
        String jfurl = jazUserOrderDO.getSignatureJia();
        String jffName = jfurl.trim();
        jffName = jffName.substring(jffName.lastIndexOf("/")+1);
        String savePath = RootPath("/img");
        //System.out.println("++++++++++++++++++++++++++++++++++++++乙方图片："+savePath);
        //将阿里云链接存到本地
        download(jfurl,jffName,savePath);
        jfImageEntity.setUrl(RootPath("/img/"+jffName));
        jfImageEntity.setType(WordImageEntity.URL);
        params.put("jfqm",jfImageEntity);//甲方签名

        params.put("yfxm", jazUserOrderDO.getNameYi()); //乙方姓名
        params.put("yfsfzhm",jazUserOrderDO.getIdentityCardYi()); //甲方身份证号码
        params.put("yfzz", jazUserOrderDO.getHomeAddressYi()); //甲方地址
        params.put("yflxdh",jazUserOrderDO.getPhoneYi()); //甲方电话

        //甲方手写签名
        WordImageEntity yfImageEntity =new WordImageEntity();
        yfImageEntity.setHeight(40);
        yfImageEntity.setWidth(34);
        String yfurl = jazUserOrderDO.getSignatureYi();
        String yffName = yfurl.trim();
        yffName = yffName.substring(yffName.lastIndexOf("/")+1);
        String yfsavePath = RootPath("/img");
        System.out.println("++++++++++++++++++++++++++++++++++++++乙方图片："+yfsavePath);

        //将阿里云链接存到本地
        download(yfurl,yffName,yfsavePath);
        yfImageEntity.setUrl(RootPath("/img/"+yffName));
        yfImageEntity.setType(WordImageEntity.URL);
        params.put("yfqm",yfImageEntity);//乙方签名

        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        String[] ksArray = splitStrArray(sdf.format(jazUserOrderDO.getStartTime()));
        String[] jsArray = splitStrArray(sdf.format(jazUserOrderDO.getEndTime()));

        params.put("ksn",ksArray[0]); //服务开始 年
        params.put("ksy",ksArray[1]); //服务开始 月
        params.put("ksr",ksArray[2]); //服务开始 日

        params.put("jsn",jsArray[0]); //服务结束 年
        params.put("jsy",jsArray[1]); //服务结束 月
        params.put("jsr",jsArray[2]); //服务结束 日

        params.put("fwdz",jazUserOrderDO.getAddress());//服务地址

        params.put("xz",jazUserOrderDO.getTotalPrice()); //薪资
        params.put("htrq",sdf.format(jazUserOrderDO.getCreateTime())); //合同签订日期

        XWPFDocument word = WordExportUtil.exportWord07(templateFile(wjm).getPath(),params);

        response.setHeader("content-disposition","attachment;filename="+new String(filename.getBytes(),"ISO8859-1"));
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        word.write(response.getOutputStream());

    }

    public String[] splitStrArray(String str) {
        if (str != null) {
            return str.split("-");
        }
        return null;
    }

    /**
     * 私有处理方法
     */
    private String RootPath(String u_path) {
        String rootPath = "";
        //windows下
        if ("\\".equals(File.separator)) {
            //System.out.println(classPath);
            rootPath = classPath + u_path;
            rootPath = rootPath.replaceAll("/", "\\\\");
            if (rootPath.substring(0, 1).equals("\\")) {
                rootPath = rootPath.substring(1);
            }
        }
        //linux下
        if ("/".equals(File.separator)) {
            //System.out.println(classPath);
            rootPath = classPath + u_path;
            rootPath = rootPath.replaceAll("\\\\", "/");
        }
        return rootPath;
    }

    //获取docx文件位置
    private File templateFile(String wjm){
        File templateFile= new File(RootPath("/"+wjm+".docx"));
        System.out.printf("++++++++++++++++++++++++++++++++++++++++++++++"+templateFile.getPath());
        return templateFile;
    }

    /*根据阿里云地址保存到本地*/
    public void download(String urlString, String filename,String savePath) throws Exception {
        // 构造URL
        URL url = new URL(urlString);
        // 打开连接
        URLConnection con = url.openConnection();
        //设置请求超时为5s
        con.setConnectTimeout(5*1000);
        // 输入流
        InputStream is = con.getInputStream();
        // 1K的数据缓冲
        byte[] bs = new byte[1024];
        // 读取到的数据长度
        int len;
        // 输出的文件流
        File sf=new File(savePath);
        if(!sf.exists()){
            sf.mkdirs();
        }
        OutputStream os = new FileOutputStream(sf.getPath()+"/"+filename);
        // 开始读取
        while ((len = is.read(bs)) != -1) {
            os.write(bs, 0, len);
        }
        // 完毕，关闭所有链接
        os.close();
        is.close();
    }

    /**
     * 随机二十位数字
     * @return
     */
    public static String tweenRandom(){
        // 创建Random对象
        Random random = new Random();
        // 生成20位的随机数字字符串
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 20; i++) {
            // 生成0-9的随机数
            int digit = random.nextInt(10);
            sb.append(digit);
        }
        // 输出随机数
        return sb.toString();
    }
}
